import Axios, { type AxiosInstance, type AxiosError, type AxiosResponse, type AxiosRequestConfig } from "axios";
import { ContentTypeEnum, ResultEnum } from "@/enums/request-enum";
import { getDeviceType } from "@/utils";
import { showFailToast } from "vant";
import "vant/es/toast/style";
import { parse, stringify, isSafeNumber } from "lossless-json";
interface responseData<T> {
    code: number;
    data: T;
    msg: string;
    [key: string]: any;
}
const parseAndValidateNumber = value => {
    if (!isSafeNumber(value)) {
        return `${value}`;
    }
    return Number(value);
};
// 默认 axios 实例请求配置
const configDefault = {
    headers: {
        "Content-Type": ContentTypeEnum.JSON
    },
    timeout: 0,
    baseURL: import.meta.env.VITE_BASE_URL,
    data: {}
};
class Http {
    // 当前实例
    private static axiosInstance: AxiosInstance;
    // 请求配置
    private static axiosConfigDefault: AxiosRequestConfig;

    // 请求拦截
    private httpInterceptorsRequest(): void {
        Http.axiosInstance.interceptors.request.use(
            config => {
                // 发送请求前，可在此携带 token
                const { type, isFormData } = config;
                config.responseType = "text";
                config.headers["tenant-id"] = import.meta.env.VITE_APP_TENANT_ID;
                if (!config.url.includes("replacementToken") && !type) {
                    config.headers["authorization"] = localStorage.getItem("token");
                    config.headers["terminal"] = window.TongBridge?.deviceType === "IOS" || getDeviceType() === "IOS" ? 30 : 20;
                }
                if (isFormData) {
                    config.headers["Content-Type"] = ContentTypeEnum.FORM_DATA;
                }

                return config;
            },
            (error: AxiosError) => {
                showFailToast(error.message);
                return Promise.reject(error);
            }
        );
    }

    // 响应拦截
    private httpInterceptorsResponse(): void {
        Http.axiosInstance.interceptors.response.use(
            (response: AxiosResponse) => {
                // 与后端协定的返回字段
                let resultText = response.data;
                let fixJson: responseData<any> = parse(resultText, null, parseAndValidateNumber) as responseData<any>;
                resultText = stringify(fixJson);
                fixJson = JSON.parse(resultText);
                // const { message } = response.data;
                const { code, data } = fixJson;
                // 判断请求是否成功
                const isSuccess = Reflect.has(fixJson, "code") && code === ResultEnum.SUCCESS;
                if (isSuccess || response?.config?.noCheck) {
                    return fixJson;
                } else {
                    // 处理请求错误
                    // showFailToast(message);
                    const data = JSON.parse(response.data);
                    console.log(data);
                    if (data.code == 401) {
                        window.TongBridge?.tokenExpired();
                        // return Promise.reject("登录过期，请重新进入页面");
                    }
                    return Promise.reject(data);
                }
            },
            (error: AxiosError) => {
                // 处理 HTTP 网络错误
                let message = "";
                // HTTP 状态码
                const status = error.response?.status;
                switch (status) {
                    case 400:
                        message = "请求错误";
                        break;
                    case 401:
                        message = "未授权，请登录";
                        break;
                    case 403:
                        message = "拒绝访问";
                        break;
                    case 404:
                        message = `请求地址出错: ${error.response?.config?.url}`;
                        break;
                    case 408:
                        message = "请求超时";
                        break;
                    case 500:
                        message = "服务器内部错误";
                        break;
                    case 501:
                        message = "服务未实现";
                        break;
                    case 502:
                        message = "网关错误";
                        break;
                    case 503:
                        message = "服务不可用";
                        break;
                    case 504:
                        message = "网关超时";
                        break;
                    case 505:
                        message = "HTTP版本不受支持";
                        break;
                    default:
                        message = "网络连接故障";
                }
                console.log(message);
                // showFailToast(message);
                return Promise.reject(message);
            }
        );
    }

    constructor(config: AxiosRequestConfig) {
        Http.axiosConfigDefault = config;
        Http.axiosInstance = Axios.create(config);
        this.httpInterceptorsRequest();
        this.httpInterceptorsResponse();
    }

    // 通用请求函数
    public request<T>(paramConfig: AxiosRequestConfig): Promise<responseData<T>> {
        const config = { ...Http.axiosConfigDefault, ...paramConfig };
        return new Promise((resolve, reject) => {
            Http.axiosInstance
                .request(config)
                .then((response: any) => {
                    resolve(response);
                })
                .catch(error => {
                    reject(error);
                });
        });
    }
}

export const http = new Http(configDefault);
